package com.ygqh.baby.service.impl;

import com.ygqh.baby.ao.*;
import com.ygqh.baby.constant.Constant;
import com.ygqh.baby.exception.YgException;
import com.ygqh.baby.mapper.YgRechargeMemberRecordMapper;
import com.ygqh.baby.po.*;
import com.ygqh.baby.service.*;
import com.ygqh.baby.utils.DateConvertUtils;
import com.ygqh.baby.utils.ExceptionUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Service
public class YgRechargeMemberRecordServiceImpl implements YgRechargeMemberRecordService {
	protected final Logger logger = Logger.getLogger(this.getClass());

	@Autowired
	private YgRechargeMemberRecordMapper ygRechargeMemberRecordMapper;
	@Autowired
	private YgUserMemberService ygUserMemberService;
	@Autowired
	private YgOrderDetailService ygOrderDetailService;
	@Autowired
	private YgSkuService ygSkuService;
	@Autowired
	private YgProductService ygProductService;
	@Autowired
	private YgProductImagesService ygProductImagesService;
	@Autowired
	private YgOrderService ygOrderService;
	@Autowired
	private YgOrderLogService ygOrderLogService;
	@Autowired
	private YgStockService ygStockService;
	@Autowired
	private YgUserService ygUserService;
	@Autowired
	private YgCardCouponDetailService ygCardCouponDetailService;
	@Autowired
	private YgAgentService ygAgentService;
	@Autowired
	private YgAgentInviteRecordService ygAgentInviteRecordService;

	@Override
	public List<YgRechargeMemberRecord> find() {
		YgRechargeMemberRecordExample example = new YgRechargeMemberRecordExample();
		example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
		return ygRechargeMemberRecordMapper.selectByExample(example);
	}

	@Override
	public int findCount() {
		YgRechargeMemberRecordExample example = new YgRechargeMemberRecordExample();
		example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
		return ygRechargeMemberRecordMapper.countByExample(example);
	}

	@Override
	public YgRechargeMemberRecord findById(Long id) {
		return ygRechargeMemberRecordMapper.selectByPrimaryKey(id);
	}

	@Override
	public int save(YgRechargeMemberRecord ygRechargeMemberRecord) {
		return ygRechargeMemberRecordMapper.insertSelective(ygRechargeMemberRecord);
	}

	@Override
	public int update(YgRechargeMemberRecord ygRechargeMemberRecord) {
		return ygRechargeMemberRecordMapper.updateByPrimaryKeySelective(ygRechargeMemberRecord);
	}

	@Override
	public ResultSet<YgRechargeMemberRecord> search(QueryInfo queryInfo, String q, String nickName,
													CodeType rechargeRecordType) {
		int count = ygRechargeMemberRecordMapper.countSuper(q, nickName, rechargeRecordType);
		if (count == 0) {
			return new ResultSet<>();
		}
		List<YgRechargeMemberRecord> list = ygRechargeMemberRecordMapper.selectSuper(queryInfo, q, nickName, rechargeRecordType);
		return new ResultSet<>(count, list);
	}

	@Override
	public int deleteSoft(Long[] ids) {
		Assert.notEmpty(ids);
		YgRechargeMemberRecordExample example = new YgRechargeMemberRecordExample();
		example.createCriteria().andIdIn(Arrays.asList(ids));
		YgRechargeMemberRecord record = new YgRechargeMemberRecord();
		record.setStatus(DataStatus.Delete);

		return ygRechargeMemberRecordMapper.updateByExampleSelective(record, example);
	}

	@Override
	public int deleteSoft(Long id) {
		return this.deleteSoft(new Long[]{id});
	}

	@Override
	public int saveOrUpdate(YgRechargeMemberRecord ygRechargeMemberRecord) {
		int r = 0;
		if (ygRechargeMemberRecord.getId() != null) {
			r = this.update(ygRechargeMemberRecord);
		} else {
			r = this.save(ygRechargeMemberRecord);
		}
		return r;
	}

	@Override
	public void doPaySuccessBusiness(Long paymentCode, BigDecimal paidPrice, Long userId, String transactionId, String cardIds, Date birthday) {
		try {
			YgRechargeMemberRecord record = this.findByPaymentCode(paymentCode);
			if (record != null) {
				if (record.getPaidPrice().compareTo(new BigDecimal(0)) > 0) {
					logger.warn("重复支付; paymentCode=" + paymentCode + ";transactionId=" + transactionId + ";paidPrice=" + paidPrice);
				} else {
					// 设置用户表登记，会员表有效期
					Date currentDate = new Date();
					Date endTime = DateConvertUtils.addYear(currentDate, 1);
					ygUserMemberService.becomeToMember(userId, currentDate, endTime, birthday);

					// 回写明细表
					record.setTransactionId(transactionId);
					record.setPaidPrice(paidPrice);
					record.setPaidTime(currentDate);
					this.update(record);
					// 生成卡券
					ygCardCouponDetailService.generateCardCouponBatch(userId, cardIds, paymentCode, "PaySuccess");
					YgUser user = ygUserService.findById(userId);
					user.setLevel(10);
					ygUserMemberService.sendQueenCoupon(user);
				}
			} else {
				logger.warn("不存在该条支付流水。 paymentCode=" + paymentCode + ";transactionId=" + transactionId + ";paidPrice=" + paidPrice);
			}
		} catch (Exception e) {
			logger.error(paymentCode + ";" + e.getMessage());
			e.printStackTrace();
		}

	}

	@Override
	public YgRechargeMemberRecord findByPaymentCode(Long parmentCode) {
		YgRechargeMemberRecordExample example = new YgRechargeMemberRecordExample();
		example.createCriteria().andPaymentCodeEqualTo(parmentCode).andStatusEqualTo(DataStatus.Valid.name());
		List<YgRechargeMemberRecord> list = ygRechargeMemberRecordMapper.selectByExample(example);
		if (CollectionUtils.isEmpty(list)) {
			return null;
		}
		return list.get(0);
	}

	@Override
	public int addRecord(Long userId, Long paymentCode, BigDecimal memberPrice, String memberType, PayType payType,
						 AppType appType) {
		return this.addRecord(userId, paymentCode, memberPrice, memberType, payType, appType, null);
	}

	@Override
	public int addRecord(Long userId, Long paymentCode, BigDecimal memberPrice, String memberType, PayType payType,
						 AppType appType, String remark) {
		return addRecord(userId, paymentCode, memberPrice, memberType, payType, appType, remark,
				CodeType.RechargeMB, Constant.YIIGOO_PLATFORM_NO);
	}

	@Override
	public int addRecord(Long userId, Long paymentCode, BigDecimal memberPrice, String memberType, PayType payType,
						 AppType appType, String remark, CodeType rechargeRecordType, String platformNo) {
		YgRechargeMemberRecord memberRecord = new YgRechargeMemberRecord();
		memberRecord.setUserId(userId);
		memberRecord.setPaymentCode(paymentCode);
		memberRecord.setMemberPrice(memberPrice);
		memberRecord.setMemberType(memberType);
		memberRecord.setPayType(payType);
		memberRecord.setAppType(appType);
		memberRecord.setCreateTime(new Date());
		memberRecord.setRemark(remark);
		memberRecord.setRechargeRecordType(rechargeRecordType);
		memberRecord.setPlatformNo(platformNo);
		return this.save(memberRecord);
	}

	@Override
	public Message saveMemberOrder(YgUser user, Long paymentCode, YgUserAddress addressInfo, String skuIds) {

		BigDecimal zero = new BigDecimal("0.00");
		Long quantity = 1L;

		YgOrder order = new YgOrder();
		// 设置收货信息
		order.setReceiver(addressInfo.getReceiver());
		order.setTelPhone(addressInfo.getTelPhone());
		order.setProvinceName(addressInfo.getProvinceName());
		order.setCityName(addressInfo.getCityName());
		order.setAreaName(addressInfo.getAreaName());
		order.setAddress(addressInfo.getAddress());
		// 保存主单

		order.setOrderId(paymentCode);
		order.setParentId(paymentCode);
		order.setUserId(user.getId());
		order.setTotalPrice(zero);
		order.setProductPrice(zero);
		order.setExpressPrice(zero);
		order.setManjianPrice(zero);
		order.setYouhuijuanPrice(zero);
		order.setGroupDisPrice(zero);
		order.setNewCustomDisPrice(zero);
		order.setPackDisPrice(zero);
		order.setBmdisPrice(zero);
		order.setPayType(PayType.Account);
		order.setPaidTime(new Date());
		order.setSupplierId(1L);
		order.setOrderStatus(OrderStatus.WaitingSend);
		order.setCreateTime(new Date());
		order.setAccountPrice(zero);
		order.setOrderType(OrderType.Ordinary);
		order.setStatus(DataStatus.Delete);
		List<YgStock> stocks = new ArrayList<YgStock>();

		List<YgOrderDetail> detailList = new ArrayList<YgOrderDetail>();

		String[] skuArr = skuIds.split(",");
		for (String skuId : skuArr) {

			YgSku sku = ygSkuService.findById(Long.parseLong(skuId));
			YgProduct product = ygProductService.findById(sku.getProductId());
			YgProductImages images = ygProductImagesService.findMainImgByProductId(product.getId());
			YgOrderDetail detail = new YgOrderDetail();
			detail.setOrderId(paymentCode);
			detail.setProductName(product.getProductName());
			detail.setPromotionType(PromotionType.ManZeng);
			detail.setQuantity(quantity);
			detail.setSize(sku.getSizeName());
			detail.setSupplierId(1L);
			detail.setSkuCode(sku.getSkuCode());
			detail.setSkuId(sku.getId());
			detail.setUnitName(product.getUnitName());
			detail.setImageUrl(images.getImagePath());
			detail.setShortName(product.getShortName());

			detail.setSalePrice(zero);
			detailList.add(detail);

			YgStock stock = new YgStock();
			stock.setSkuCode(sku.getSkuCode());
			stock.setAmount(quantity);
			stocks.add(stock);
		}

		try {
			ygOrderService.save(order);
			ygOrderLogService.addOrderLog(order.getOrderId(), order.getOrderStatus(), addressInfo.getTelPhone(), "主订单保存成功 ;order=" + order.toString());
		} catch (Exception e) {
			ygOrderLogService.addOrderLog(order.getOrderId(), order.getOrderStatus(), addressInfo.getTelPhone(), "主订单保存失败;order=" + order.toString());
			logger.error("主单保存失败。orderInfo:" + order.toString());
			e.printStackTrace();
			return Message.error("提交订单失败！", paymentCode);
		}

		ygOrderDetailService.addBatch(detailList);
		// 扣减库存
		ygStockService.reduceStock(stocks, "saveMemberOrder");

		return Message.success(order.getOrderId());

	}

	@Override
	public YgRechargeMemberRecord findPaySuccessRecordByUserId(Long userId) {
		YgRechargeMemberRecordExample example = new YgRechargeMemberRecordExample();
		example.createCriteria().andUserIdEqualTo(userId).andStatusEqualTo(DataStatus.Valid.name()).andPaidTimeIsNotNull();
		List<YgRechargeMemberRecord> list = ygRechargeMemberRecordMapper.selectByExample(example);
		if (!CollectionUtils.isEmpty(list)) {
			return list.get(0);
		}
		return null;
	}

	@Override
	public void doPaySuccessBusiness(Long paymentCode, BigDecimal paidPrice, Long userId, String transactionId) {
		try {
			YgRechargeMemberRecord record = this.findByPaymentCode(paymentCode);
			if (record != null) {
				if (record.getPaidPrice().compareTo(new BigDecimal(0)) > 0) {
					logger.warn("重复支付; paymentCode=" + paymentCode + ";transactionId=" + transactionId + ";paidPrice=" + paidPrice);
				} else {
					Date currentDate = new Date();
					// 回写明细表
					record.setTransactionId(transactionId);
					record.setPaidPrice(paidPrice);
					record.setPaidTime(currentDate);
					this.update(record);

					YgUser user = ygUserService.findById(userId);
					if (CodeType.RechargeMB.equals(record.getRechargeRecordType())) {
						// 设置用户表登记，会员表有效期
						Date endTime = DateConvertUtils.addYear(currentDate, 1);
						ygUserMemberService.becomeToMember(userId, currentDate, endTime, record.getRemark());

						//发会员券
						ygUserMemberService.sendQueenCoupon(user);
					} else if (CodeType.RechargeAG.equals(record.getRechargeRecordType())) {
						// 充值代理
						if (StringUtils.isNotBlank(record.getRemark())) {
							// 判断充值记录是否有source，如果存在并且充值用户无邀请用户，则绑定邀请用户
							ygAgentInviteRecordService.processFromCodeByUserAgent(user, record.getRemark());
						}
						if (UserType.UserAgent.equals(user.getUserType())) {
							// 用户已经是代理
							throw new YgException("用户" + user.getUserName() + "已经是代理，出现二次支付；" +
									"paymentCode=" + paymentCode + ";transactionId=" + transactionId + ";paidPrice=" + paidPrice);
						}
						ygAgentService.rechargeUserAgent(user, "rechargeUserAgentByPay", record.getPlatformNo());
					}
				}
			} else {
				logger.warn("不存在该条支付流水。 paymentCode=" + paymentCode + ";transactionId=" + transactionId + ";paidPrice=" + paidPrice);
			}
		} catch (Exception e) {
			logger.error(paymentCode + ";" + ExceptionUtil.getExceptionMsg(e));
			e.printStackTrace();
		}
	}

	@Override
	public ResultSet<YgRechargeMemberRecord> searchCountVip(QueryInfo queryInfo, CodeType rechargeRecordType) {
		int count = ygRechargeMemberRecordMapper.countVip(rechargeRecordType);
		if (count == 0) {
			return new ResultSet<>();
		}
		List<YgRechargeMemberRecord> list = ygRechargeMemberRecordMapper.selectCountVip(queryInfo, rechargeRecordType);
		return new ResultSet<>(count, list);
	}

	@Override
	public ResultSet<YgRechargeMemberRecord> searchRecordByUserId(Long userId, CodeType rechargeRecordType) {
		YgRechargeMemberRecordExample example = new YgRechargeMemberRecordExample();
		YgRechargeMemberRecordExample.Criteria criteria = example.createCriteria()
				.andUserIdEqualTo(userId)
				.andStatusEqualTo(DataStatus.Valid.name())
				.andPaidPriceGreaterThan(new BigDecimal(0));
		if (rechargeRecordType != null) {
			criteria.andRechargeRecordTypeEqualTo(rechargeRecordType.name());
		}
		example.setOrderByClause("paid_time desc");
		List<YgRechargeMemberRecord> list = ygRechargeMemberRecordMapper.selectByExample(example);
		return new ResultSet<>(1, list);
	}

	@Override
	public void refundSuccess(YgRechargeMemberRecord rechargeMemberRecord, String handler, String remark) {
		// 修改原充值记录的信息
		this.refundRecord(rechargeMemberRecord.getId(), handler, remark);

		YgUserMember userMember = ygUserMemberService.findByUserId(rechargeMemberRecord.getUserId());
		Date newEndTime = DateConvertUtils.addYear(userMember.getMemberEndTime(), -1);
		if (newEndTime.before(new Date())) {
			// 新结束日期小于今天，关闭会员
			closeUserVip(rechargeMemberRecord.getUserId());
		}
		// 更新会员记录信息
		YgUserMember updateRecord = new YgUserMember();
		updateRecord.setId(userMember.getId());
		updateRecord.setMemberEndTime(newEndTime);
		updateRecord.setUpdateTime(new Date());
		updateRecord.setUpdateBy(handler);
		ygUserMemberService.update(updateRecord);
	}

	@Override
	public void refundRecord(Long id, String handler, String remark) {
		YgRechargeMemberRecord record = new YgRechargeMemberRecord();
		record.setId(id);
		record.setRefundTime(new Date());
		record.setRefundBy(handler);
		record.setRemark(remark);
		this.update(record);
	}

	private void closeUserVip(Long userId) {
		YgUser ygUser = new YgUser();
		ygUser.setId(userId);
		ygUser.setLevel(1);
		ygUser.setUpdateTime(new Date());
		ygUserService.updateUserInfo(ygUser);
	}
}
